/*
*    Qizx/open 3.0 beta
*
* This code is the open-source version of Qizx.
* Copyright (C) 2004-2009 Axyana Software -- All rights reserved.
*
* The contents of this file are subject to the Mozilla Public License 
*  Version 1.1 (the "License"); you may not use this file except in 
*  compliance with the License. You may obtain a copy of the License at
*  http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
*  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
*  for the specific language governing rights and limitations under the
*  License.
*
* The Initial Developer of the Original Code is Xavier Franc - Axyana Software.
*
*/
using System;
using EvaluationException = System.Qizx.Api.EvaluationException;
using ItemType = System.Qizx.Api.ItemType;
using Node = System.Qizx.Api.Node;
using QizxException = System.Qizx.Api.QizxException;
using XQDateTimeBase = System.Qizx.Api.Util.XQDateTimeBase;
using Duration = System.Qizx.Api.Util.XQDuration;
using BasicNode = System.Qizx.Xdm.BasicNode;
using BaseValue = System.Qizx.XQuery.BaseValue;
using ComparisonContext = System.Qizx.XQuery.ComparisonContext;
using XQItem = System.Qizx.XQuery.XQItem;
using XQItemType = System.Qizx.XQuery.XQItemType;
using XQType = System.Qizx.XQuery.XQType;
namespace System.Qizx.XQuery.Dt {

    /// <summary> Generic Value implementation.
    /// <p>
    /// Abstract class for variant values, like those returned by Sequence or Flower
    /// expressions. Holds a current item and delegates all methods to this current
    /// item.
    /// </summary>
    public abstract class GenericValue : BaseValue {
        public override ItemType ValueType {
            get {
                return item != null ? item.ValueType : (ItemType)XQType.ITEM;
            }

        }
        public override XQItemType ItemType {
            get {
                return item != null ? item.ItemType : XQType.ITEM;
            }

        }
        public override XQItem Item {
            get {
                //        if (item == null) {
                //            System.err.println("null item in " + this);
                //            Thread.dumpStack();
                //        }
                return item;
            }

        }
        public override bool ValueAsBoolean {
            get {
                return item.ValueAsBoolean;
            }

        }
        public override long ValueAsInteger {
            get {
                return item.ValueAsInteger;
            }

        }

        public override System.Decimal ValueAsDecimal {
            get {
                return item.ValueAsDecimal;
            }
        }

        public override System.Qizx.Api.QName ValueAsQName {
            get {
                return item.ValueAsQName;
            }
        }

        public override double ValueAsDouble {
            get {
                return item.ValueAsDouble;
            }

        }
        public override float ValueAsFloat {
            get {
                return item.ValueAsFloat;
            }

        }
        public override string ValueAsString {
            get {
                if (item == null) {
                    System.Console.Error.WriteLine("null item in " + this);
                    //TODO System.Console.Out.WriteLine(System.Enviroment.StackTrace);
                }
                return item.ValueAsString;
            }

        }
        public override Duration Duration {
            get {
                return item.Duration;
            }

        }
        public override XQDateTimeBase ValueAsMoment {
            get {
                return item.ValueAsMoment;
            }

        }
        protected internal XQItem item;

        public override XQItem AsAtom() {
            if (item.IsNode)
                try {
                    item = new SingleString(item.GetNode().StringValue, XQType.UNTYPED_ATOMIC);
                } catch (QizxException shouldNotHappen) {
                    return item; //OOPS sure?
                }
            return item;
        }

        public override Node GetNode() {
            if (item == null) {
                throw new EvaluationException("null item!");
            }
            return item.GetNode();
        }

        public override BasicNode GetBasicNode() {
            if (item == null)
                throw new System.SystemException("null item!");
            return item.GetBasicNode();
        }

        public override bool IsNode {
            get {
                // -if(item == null) System.err.println(" OOOPS "+ this);
                return item != null && item.IsNode;
            }
        }

        public override int CompareTo(XQItem that, ComparisonContext context, int flags) {
            return item.CompareTo(that, context, 0);
        }

        public override bool Equals(System.Object that) {
            return item.Equals(that);
        }

        public override int GetHashCode() {
            return item == null ? 0 : item.GetHashCode();
        }
    }
}